package com.blue.gateway.utils;

import java.math.BigDecimal;

public class BigDecimalUtil {

    private static final int DEFAULT_SCALE = 2;
    private static final int DEFAULT_ROUND_MODE = BigDecimal.ROUND_HALF_UP;

    // 这个类不能实例化
    private BigDecimalUtil() {
    }

    /**
     * BigDecimal 加法
     *
     * @param params
     * @return
     */
    public static BigDecimal add(BigDecimal... params) {
        if (params == null || params.length == 0) {
            return BigDecimal.ZERO;
        }
        BigDecimal total = BigDecimal.ZERO;
        for (BigDecimal param : params) {
            if (param != null) {
                total = total.add(param);
            }
        }
        return total;
    }

    /**
     * double 加法
     *
     * @param params
     * @return
     */
    public static BigDecimal add(double... params) {
        if (params == null || params.length == 0) {
            return BigDecimal.ZERO;
        }
        BigDecimal total = BigDecimal.ZERO;
        for (double param : params) {
            total = total.add(new BigDecimal(Double.toString(param)));
        }
        return total;
    }

    /**
     * BigDecimal 减法
     *
     * @param params
     * @return
     */
    public static BigDecimal subtract(BigDecimal... params) {
        if (params == null || params.length == 0 || params[0] == null) {
            return BigDecimal.ZERO;
        }
        BigDecimal total = params[0];
        for (int i = 1, len = params.length; i < len; i++) {
            if (params[i] != null) {
                total = total.subtract(params[i]);
            }
        }
        return total;
    }

    /**
     * double 减法
     *
     * @param params
     * @return
     */
    public static BigDecimal subtract(double... params) {
        if (params == null || params.length == 0) {
            return BigDecimal.ZERO;
        }
        BigDecimal total = new BigDecimal(Double.toString(params[0]));
        for (int i = 1, len = params.length; i < len; i++) {
            total = total.subtract(new BigDecimal(Double.toString(params[i])));
        }
        return total;
    }


    /**
     * BigDecimal 乘法
     *
     * @param params
     * @return
     */
    public static BigDecimal multiply(BigDecimal... params) {
        if (params == null || params.length == 0) {
            return BigDecimal.ZERO;
        }
        BigDecimal total = BigDecimal.ONE;
        for (BigDecimal param : params) {
            if (param != null) {
                total = total.multiply(param);
            }
        }
        return total.setScale(DEFAULT_SCALE, DEFAULT_ROUND_MODE);
    }

    /**
     * BigDecimal 乘法
     *
     * @param param
     * @return
     */
    public static long multiply1000(BigDecimal param) {
        if (param == null) {
            return 0L;
        }
        return param.multiply(BigDecimal.valueOf(1000)).longValue();
    }

    /**
     * BigDecimal 乘法
     *
     * @param param
     * @return
     */
    public static long multiply100(BigDecimal param) {
        if (param == null) {
            return 0L;
        }
        return param.multiply(BigDecimal.valueOf(100)).longValue();
    }

    /**
     * double 乘法
     *
     * @param params
     * @return
     */
    public static BigDecimal multiply(double... params) {
        if (params == null || params.length == 0) {
            return BigDecimal.ZERO;
        }
        BigDecimal total = BigDecimal.ONE;
        for (double param : params) {
            total = total.multiply(new BigDecimal(Double.toString(param)));
        }
        return total.setScale(DEFAULT_SCALE, DEFAULT_ROUND_MODE);
    }


    /**
     * BigDecimal 除法
     *
     * @param params
     * @return
     */
    public static BigDecimal divide(BigDecimal... params) {
        return divide(DEFAULT_SCALE, params);
    }

    /**
     * BigDecimal 除法
     *
     * @param scale 保留几位小数
     * @param params
     * @return
     */
    public static BigDecimal divide(int scale, BigDecimal... params) {
        if (params == null || params.length == 0 || params[0] == null) {
            return BigDecimal.ZERO;
        }
        BigDecimal total = params[0];
        for (int i = 1, len = params.length; i < len; i++) {
            if (params[i] != null) {
                total = total.divide(params[i], 10, DEFAULT_ROUND_MODE);
            }
        }
        return total.setScale(scale, DEFAULT_ROUND_MODE);
    }

    /**
     * double 除法
     *
     * @param params
     * @return
     */
    public static BigDecimal divide(double... params) {
        if (params == null || params.length == 0) {
            return BigDecimal.ZERO;
        }
        BigDecimal total = new BigDecimal(Double.toString(params[0]));
        for (int i = 1, len = params.length; i < len; i++) {
            total = total.divide(new BigDecimal(Double.toString(params[i])), 10, DEFAULT_ROUND_MODE);
        }
        return total.setScale(DEFAULT_SCALE, DEFAULT_ROUND_MODE);
    }

    /**
     * 四舍五入取得double的值
     *
     * @param value,如果是null，将转化成0
     * @param scale               表示表示需要精确到小数点以后几位
     * @return
     */
    public static BigDecimal round(BigDecimal value, int scale) {
        if (value == null) {
            return BigDecimal.ZERO;
        }
        return value.setScale(scale, DEFAULT_ROUND_MODE);
    }

    /**
     * 乘以1000
     *
     * @param value
     * @return
     */
    public static BigDecimal mulBy1000(BigDecimal value) {
        if (value == null) {
            return BigDecimal.ZERO;
        }
        return value.multiply(new BigDecimal("1000"));
    }

    /**
     * 除以1000
     *
     * @param value
     * @return
     */
    public static BigDecimal divideBy1000(BigDecimal value) {
        if (value == null) {
            return BigDecimal.ZERO;
        }
        return value.divide(new BigDecimal("1000")).setScale(DEFAULT_SCALE, DEFAULT_ROUND_MODE);
    }

    /**
     * 相等 (equal)
     *
     * @param val1
     * @param val2
     * @return
     */
    public static boolean eq(BigDecimal val1, BigDecimal val2) {
        return val1 != null && val2 != null && val1.compareTo(val2) == 0;
    }

    /**
     * 不相等 (not equal)
     *
     * @param val1
     * @param val2
     * @return
     */
    public static boolean ne(BigDecimal val1, BigDecimal val2) {
        return !eq(val1, val2);
    }

    /**
     * 判断是否>0 (greater than)
     *
     * @param value
     * @return
     */
    public static boolean gtZero(BigDecimal value) {
        return value != null && value.compareTo(BigDecimal.ZERO) > 0;
    }

    /**
     * 判断是否>=0 (greater than or equal)
     *
     * @param value
     * @return
     */
    public static boolean geZero(BigDecimal value) {
        return value != null && value.compareTo(BigDecimal.ZERO) >= 0;
    }

    /**
     * 判断是否=0 (equal)
     *
     * @param value
     */
    public static boolean eqZero(BigDecimal value) {
        return value != null && value.compareTo(BigDecimal.ZERO) == 0;
    }

    /**
     * 判断是否=0 (equal)
     *
     * @param value
     */
    public static boolean eqZeroOrNull(BigDecimal value) {
        return value == null || value.compareTo(BigDecimal.ZERO) == 0;
    }

    /**
     * 判断是否=0 (equal)
     *
     * @param value
     */
    public static boolean ltZeroOrNull(BigDecimal value) {
        return value == null || value.compareTo(BigDecimal.ZERO) < 0;
    }
    /**
     * 判断是否<0 (less than) null当做<0处理
     *
     * @param value
     */
    public static boolean ltZero(BigDecimal value) {
        return value == null || value.compareTo(BigDecimal.ZERO) < 0;
    }

    /**
     * 判断是否<=0 (less than or equal) null当做<=0处理
     *
     * @param value
     */
    public static boolean leZero(BigDecimal value) {
        return value == null || value.compareTo(BigDecimal.ZERO) <= 0;
    }

    /**
     * 值比较 (如果val1>val2，返回true)
     * @param val1
     * @param val2
     */
    public static boolean gt(BigDecimal val1, BigDecimal val2) {
        return val1 != null && val2 != null && val1.compareTo(val2) > 0;
    }

    /**
     * 值比较 (如果val1>=val2，返回true)
     * @param val1
     * @param val2
     */
    public static boolean ge(BigDecimal val1, BigDecimal val2) {
        return val1 != null && val2 != null && val1.compareTo(val2) >= 0;
    }

    /**
     * 获取最小值
     *
     * @param values
     * @return
     */
    public static BigDecimal min(BigDecimal... values) {
        if (values == null || values.length == 0) {
            return BigDecimal.ZERO;
        }
        BigDecimal result = values[0];
        for (int n = 1, len = values.length; n < len; n++) {
            if(result == null) {
                result = values[n];
            } else {
                if (values[n] != null) {
                    result = result.min(values[n]);
                }
            }
        }
        return result;
    }

    /**
     * 获取最小值
     *
     * @param values
     * @return
     */
    public static BigDecimal max(BigDecimal... values) {
        if (values == null || values.length == 0) {
            return BigDecimal.ZERO;
        }
        BigDecimal result = values[0];
        for (int n = 1, len = values.length; n < len; n++) {
            if(result == null) {
                result = values[n];
            } else {
                if (values[n] != null) {
                    result = result.max(values[n]);
                }
            }
        }
        return result;
    }

    /**
     * 转换为分的金额单位
     * @param amount 金额
     * @return
     */
    public static String toUnitFen(BigDecimal amount) {
        if (amount == null) {
            return "";
        }
        return String.valueOf(BigDecimalUtil.multiply(amount, BigDecimal.valueOf(100)).intValue());
    }

    public static void main(String[] args){
        System.out.println(max(null, null, null));
        System.out.println(max(BigDecimal.ONE, null, null));
        System.out.println(max(null, BigDecimal.ONE, null));
        System.out.println(max(null, null, BigDecimal.ONE));
        System.out.println(max(BigDecimal.ONE, null, BigDecimal.TEN));
        System.out.println(max(null, BigDecimal.ONE, BigDecimal.TEN));
        System.out.println(min(BigDecimal.ONE, BigDecimal.ONE));
    }


}
